<?php
declare(strict_types=1);

namespace App\Utils;

use Hyperf\Utils\Context;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
// use Hyperf\HttpServer\Contract\ResponseInterface;
use Throwable;

/**
 * 自定义函数类
 *
 * Class CustomUtils
 * @package App\Utils
 */
class CustomUtils
{

    public static function xeServiceReturnData(int $code, string $message = '', $data = []): array
    {
        $result = [
            'code' => $code,
            'message' => $message,
            'data' => $data
        ];
        
        return $result;
    }

    /**
     * 操作成功返回值包装
     * @param array $data
     * @param string $msg
     * @return array
     */
    public static function xzxResponseData(int $code, string $message = '', $data = []): array
    {
        return [
            "code"  => $code,
            "msg"   => $message == "" ? "操作成功" : $message,
            "data"  => $data
        ];
    }

    /**
     * 自定义打印调试函数
     */
    public static function xzxDebug()
    {
        // 检查环境参数
        if (!env('APP_DEBUG')) {
            return;
        }

        $args = func_get_args();

        if (PHP_SAPI !== 'cli') echo '<pre>';

        $datetime = self::xzxGetDateTime();

        echo PHP_EOL . '---------- debug print begin ----------' . PHP_EOL . PHP_EOL;

        foreach ($args as $v) {
            if (!$v) {
                var_dump($v);
            } else {
                print_r($v);
            }
            echo PHP_EOL;
        }

        echo PHP_EOL . '---------------------------------------' . PHP_EOL;

        $debug_backtrace = debug_backtrace();

        $trace = current($debug_backtrace);

        // 获取函数名
        $func = next($debug_backtrace);
        $func = !$func ? null : $func['function'];

        echo "FILE  : {$trace['file']}" . PHP_EOL;
        echo "FUNC  : {$func}" . PHP_EOL;
        echo "LINE  : {$trace['line']}" . PHP_EOL;
        echo "TIME  : {$datetime}" . PHP_EOL;

        echo '---------- debug print end   ----------' . PHP_EOL . PHP_EOL;

        if (PHP_SAPI !== 'cli') echo '</pre>';
    }

    /**
     * 时间戳转换
     *
     * @param null $time
     * @return false|string
     */
    public static function xzxGetDateTime($time = null)
    {
        if(is_null($time)){
            $time = time();
        }
        return date('Y-m-d H:i:s', $time);
    }

    /**
     * @return float
     * 获取毫秒级时间戳
     */
    public static function xzxGetMsecTime()
    {
        [$msec, $sec] = explode(' ', microtime());
        $msectime =  (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        return $msectime;
    }

    /**
     * @param $pwd
     * @param $salt
     * @return string
     */
    public static function xzxGenPassWord($pwd, $salt = "")
    {
        if ($salt = "") {
            $salt = "xzxkkkkkkk";
        }
        return  md5($pwd . '*' . $salt);
    }

    /**
     * @return mixed|string
     */
    public static function xzxGetClientIp()
    {
        try {
            /**
             * @var ServerRequestInterface $request
             */
            $request = Context::get(ServerRequestInterface::class);
            $ip_addr = $request->getHeaderLine('x-forwarded-for');
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getHeaderLine('remote-host');
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getHeaderLine('x-real-ip');
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
            $ip_addr = $request->getServerParams()['remote_addr'] ?? '0.0.0.0';
            if (self::xzxVerifyIp($ip_addr)) {
                return $ip_addr;
            }
        } catch (Throwable $e) {
            return '0.0.0.0';
        }
        return '0.0.0.0';
    }

    public static function xzxVerifyIp($realip)
    {
        return filter_var($realip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
    }

    /**
     * 根据IP获取地区
     */

    public static function getCity($ip)
    {

    }
    /**
     * 判断是否存在并且不为空
     *
     * @param $param
     *
     * @return bool
     */
    public static function xzxIsEmptyParam($param)
    {
        return (isset($param) && !empty($param));
    }

    /**
     * 当存在且不为空字符串的时候增加参数
     */
    public static function xzxAddSearch(&$param, $search, $key)
    {
        if (isset($search[$key]) && $search[$key] !== '') {

            $param[$key] = $search[$key];
        }
        return $param;
    }

    /**
     * 空对象
     */
    public static function xzxEmptyObject()
    {
        return (object)[];
    }

    /**
     * create UUID
     */
    public static function createUUID()
    {
        $charid = strtoupper(md5(uniqid((string)mt_rand(), true)));
        $hyphen = chr(45);// "-"
        $uuid = substr($charid, 0, 8) . $hyphen
        . substr($charid, 8, 4) . $hyphen
        . substr($charid, 12, 4) . $hyphen
        . substr($charid, 16, 4) . $hyphen
        . substr($charid, 20, 12);
        return $uuid;
    }

    /**
     * 生成密码
     */
    public static function genPassWord($pwd, $salt)
    {
        return  md5($pwd . '*' . $salt);
    }

    /**
     * @todo 获取当前域名
     * @return array|mixed|string
     */
    public static function getServerName() {
        $request = Context::get(ServerRequestInterface::class);
        return $request->server('server_name') ?? $request->server('http_host');
    }

    public static function getRequestUri() {
        $request = Context::get(ServerRequestInterface::class);
        return $request->server('request_uri');
    }

    /**
     * @return array|mixed|string
     * 生成appid
     */
    public static function createAppId() {
        return substr(md5(time() . NumberUtils::random(16)), 8, 24);
    }

    /**
     * @return array|mixed|string
     * 生成appid
     */
    public static function createAppSecret() {
        return sha1(md5(time() . NumberUtils::random(16)));
    }
}
